home *** CD-ROM | disk | FTP | other *** search
- /*
- File: GXEditSelection.c
-
- Contains:
-
- Written by: Barton R. House
-
- Copyright: © 1993 by Apple Computer, Inc., All rights reserved.
-
- */
-
- #include <Script.h>
-
- #include "GXEdit.h"
- #include "GXEditDoc.h"
- #include "GXEditSelection.h"
- #include "GXEditParagraph.h"
- #include "GXEditStyle.h"
- #include "GXEditDebug.h"
- #include "GXEditError.h"
-
- #include "graphics routines.h"
- #include "graphics libraries.h"
- #include "font routines.h"
- #include "math routines.h"
- #include "layout routines.h"
-
-
- void SetSelection(DocPtr dp, long start, long end, Boolean setEmptyStyle, Boolean endOfLine, Boolean setMaxLineOffset)
- {
- SelPtr sp;
- ParaPtr pp;
- NewRunPtr rp;
- short runIndex;
- short runOffset;
- AttrRec attributes;
- StylePtr emptyStyle;
- short lineIndex;
- short lineOffset;
-
- sp = &dp->selection;
-
- sp->startDocOffset = start;
- sp->endDocOffset = end;
-
- sp->endOfLine = endOfLine;
-
- GetParagraphIndexAndOffset(dp, start, &sp->startParaIndex, &sp->startParaOffset, false);
- GetParagraphIndexAndOffset(dp, end, &sp->endParaIndex, &sp->endParaOffset, endOfLine);
-
- if(start != end) {
-
- attributes.start = true;
-
- GetSelectionAttributes(dp, &attributes);
-
- dp->currentSize = attributes.size;
-
- dp->numCurrentFonts = attributes.numFonts;
- DisposeHandle((Handle) dp->currentFonts);
- dp->currentFonts = attributes.fonts;
-
- dp->numCurrentStyles = attributes.numStyles;
- DisposeHandle((Handle) dp->currentStyles);
- dp->currentStyles = attributes.styles;
-
- } else {
-
- sp->startParaOffset = sp->endParaOffset;
- sp->startParaIndex = sp->endParaIndex;
-
- pp = *dp->paragraphs + sp->startParaIndex;
-
- if(sp->startParaOffset == pp->numText && pp->numText) {
-
- /* we don't allow the caret to be placed after the paragraph mark */
-
- sp->startParaOffset--;
- sp->endParaOffset--;
- sp->startDocOffset--;
- sp->endDocOffset--;
-
- sp->endOfLine = false;
-
- }
-
- if(setEmptyStyle) {
-
- GetNewRunIndexAndOffset(dp, pp, sp->startParaOffset, &runIndex, &runOffset);
-
- rp = *pp->runs + runIndex;
-
- /* get the left run if in between runs */
-
- if(runOffset == 0 && runIndex)
- rp--;
-
- dp->emptyStyle = rp->styleIndex;
-
- /* make sure we are in the correct script/language */
-
- emptyStyle = GetDocStyle(dp, dp->emptyStyle);
-
- if(emptyStyle->script != dp->currentScript || emptyStyle->language != dp->currentLanguage) {
-
- dp->currentScript = emptyStyle->script;
- dp->currentLanguage = emptyStyle->language;
-
- /* change the keyboard script for the user */
-
- KeyScript((short) (dp->currentScript - 1));
-
- }
- }
-
- if(setMaxLineOffset) {
-
- GetLineIndexAndOffset(dp, *dp->paragraphs + sp->startParaIndex, sp->startParaOffset, &lineIndex, &lineOffset, sp->endOfLine);
-
- dp->maxLineOffset = lineOffset;
- }
-
- dp->currentSize = GetDocStyleTextSize(dp, dp->emptyStyle);
-
- dp->numCurrentFonts = 1;
- SetHandleSize((Handle) dp->currentFonts, sizeof(gxFont));
- (*dp->currentFonts)[0] = GetDocStyleTextFont(dp, dp->emptyStyle);
-
- dp->numCurrentStyles = 1;
- SetHandleSize((Handle) dp->currentStyles, sizeof(short));
- (*dp->currentStyles)[0] = dp->emptyStyle;
-
- }
-
-
- }
-
- void GetParagraphIndexAndOffset(DocPtr dp, long docOffset, short * paragraphIndexPtr,
- short * paragraphOffsetPtr, Boolean endOfLine)
- {
- ParaPtr pp;
- short numParagraphs;
- short paragraphIndex;
-
- *paragraphIndexPtr = 0; /* incase of error */
- *paragraphOffsetPtr = 0;
-
-
- pp = *dp->paragraphs;
-
- /* linear search for correct paragraph -- this should be made into a binary search */
-
- numParagraphs = dp->numParagraphs;
-
- for(paragraphIndex = 0; paragraphIndex < numParagraphs; paragraphIndex++, pp++) {
-
- if(docOffset >= pp->docOffset && docOffset < (pp->docOffset + pp->numText)) {
-
- if(endOfLine && docOffset == pp->docOffset && paragraphIndex != 0) {
- pp--;
- paragraphIndex--;
- }
-
- *paragraphIndexPtr = paragraphIndex;
- *paragraphOffsetPtr = docOffset - pp->docOffset;
-
- return;
-
- }
-
- }
-
- pp--;
- paragraphIndex--;
-
- *paragraphIndexPtr = paragraphIndex;
- *paragraphOffsetPtr = pp->numText;
-
-
- }
-
- void GetLineIndexAndOffset(DocPtr dp, ParaPtr pp, short paraOffset, short * lineIndexPtr, short * lineOffsetPtr, Boolean endOfLine)
- {
- LinePtr lp;
- short lineIndex;
-
- if(paraOffset < 0 || paraOffset > pp->numText)
- gxEditPostError(dp, gx_edit_internal_fatal_error);
-
- lp = *pp->lines;
-
- /* linear search for now */
-
- for(lineIndex=0; lineIndex < pp->numLines; lineIndex++, lp++) {
-
- if(paraOffset >= lp->paraOffset && paraOffset < (lp->paraOffset + lp->numText)) {
-
- if(endOfLine && lp->paraOffset == paraOffset && lineIndex != 0) {
- lp--;
- lineIndex--;
- }
-
- *lineIndexPtr = lineIndex;
- *lineOffsetPtr = paraOffset - lp->paraOffset;
-
- return;
-
- }
- }
-
- lp--;
- lineIndex--;
-
- *lineIndexPtr = lineIndex;
- *lineOffsetPtr = lp->numText;
-
- }
-
- void GetNewRunIndexAndOffset(DocPtr dp, ParaPtr pp, short paraOffset, short * runIndexPtr,
- short * runOffsetPtr)
- {
- NewRunPtr rp;
- short runIndex;
- short numRuns;
-
- if(paraOffset < 0 || paraOffset > pp->numText)
- gxEditPostError(dp, gx_edit_internal_fatal_error);
-
- *runIndexPtr = 0; /* in case of error */
- *runOffsetPtr = 0;
-
- rp = *pp->runs;
-
- /* linear search for now -- this should be optimized later */
-
- numRuns = pp->numRuns;
-
- for(runIndex=0; runIndex < pp->numRuns; runIndex++, rp++) {
-
- if(paraOffset >= rp->paraOffset && paraOffset < (rp->paraOffset + rp->numText)) {
-
- *runIndexPtr = runIndex;
- *runOffsetPtr = paraOffset - rp->paraOffset;
-
- break;
- }
-
- }
-
- if(runIndex == numRuns && numRuns) {
-
- /* we must want the last spot on the run */
-
- runIndex--;
- rp--;
-
- *runIndexPtr = runIndex;
- *runOffsetPtr = rp->numText;
-
- }
-
- }
-
- void GetSelectionAttributes(DocPtr dp, AttrPtr ap)
- {
- short paraIndex;
- SelPtr sp;
- ParaPtr pp;
- short startOffset;
- short endOffset;
-
- sp = &dp->selection;
-
- paraIndex = sp->startParaIndex;
-
- HLock((Handle) dp->paragraphs);
-
- pp = *dp->paragraphs + paraIndex;
-
- ap->start = true;
-
- while(paraIndex <= sp->endParaIndex) {
-
- if(paraIndex == sp->startParaIndex)
- startOffset = sp->startParaOffset;
- else
- startOffset = 0;
-
- if(paraIndex == sp->endParaIndex)
- endOffset = sp->endParaOffset;
- else
- endOffset = pp->numText;
-
- if(startOffset != endOffset)
- GetParagraphAttributes(dp, pp, ap, startOffset, endOffset);
-
- paraIndex++;
- pp++;
-
- }
-
- HUnlock((Handle) dp->paragraphs);
-
- }
-
- Boolean SetSelectionStyles(DocPtr dp, short numStyles, short * oldStyles, short * newStyles)
- {
- short paraIndex;
- SelPtr sp;
- ParaPtr pp;
- short startOffset;
- short endOffset;
- Boolean modified;
-
- sp = &dp->selection;
-
- if(sp->startDocOffset == sp->endDocOffset) {
-
- if(numStyles != 1)
- gxEditPostError(dp, gx_edit_internal_fatal_error);
- else
- dp->emptyStyle = *newStyles;
-
- return(false); /* nothing in selection */
- }
-
- paraIndex = sp->startParaIndex;
-
- HLock((Handle) dp->paragraphs);
-
- pp = *dp->paragraphs + paraIndex;
-
- modified = false;
-
- while(paraIndex <= sp->endParaIndex) {
-
- if(paraIndex == sp->startParaIndex)
- startOffset = sp->startParaOffset;
- else
- startOffset = 0;
-
- if(paraIndex == sp->endParaIndex)
- endOffset = sp->endParaOffset;
- else
- endOffset = pp->numText;
-
- if(startOffset != endOffset)
- modified |= SetParagraphStyles(dp, pp, numStyles, oldStyles, newStyles, startOffset, endOffset);
-
- paraIndex++;
- pp++;
-
- }
-
- HUnlock((Handle) dp->paragraphs);
-
- return(modified);
-
- }
-